<template>
  <div>
    <div ref="commentRef" :class="[
      'up-comment',
      {
        'up-comment--placeholder-control': placeholderControl,
        'up-comment--active': getCommentActionActive(),
      },
    ]">
      <!-- 评论列表 -->
      <div ref="commentListWrapRef" class="up-comment__list-wrap">
        <div class="up-comment__list-inner">
          <i v-show="!loaded" class="ui-icon-loading"></i>
          <ul ref="commentListRef">
            <comment-item @click.native="handleSelect(item, index)" v-for="(item, index) in list"
              v-show="item.type !== 3" :key="item.commentId" ref="commentItemRef" :data="item"></comment-item>
          </ul>
        </div>
      </div>

      <!-- 常用语列表 -->
      <div class="sideCommon">
        <div class="commonLanguage">
          <div v-for="(item, index) in commonLanguageList" :key="index" @click="send(item.content)">{{ item.content }}
          </div>
        </div>
      </div>


      <!-- /评论列表 -->

      <!-- 新消息提示 -->
      <div v-show="moreList.length > 0" class="up-comment__more" @click="more">
        {{ moreList.length > 99 ? '99+' : moreList.length }} 条新消息
      </div>
      <!-- /新消息提示 -->

      <!-- 评论、点赞 -->
      <div class="up-comment__action">
        <comment-action ref="commentActionRef" @send="commentActionSend"></comment-action>
      </div>
    </div>
    <u-action-sheet :round="12" :actions="actionlist" @select="selectClick" :show="show" @close="show = false"
      cancelText="取消"></u-action-sheet>
  </div>
</template>

<script>
import BScroll from '@better-scroll/core';
import MouseWheel from '@better-scroll/mouse-wheel';
import { notRepeat, SourceEnum, SystemNoticeEnum } from '@/static/tim.js';
import liveInfo from '@/mixins/liveInfo';
import liveSetting from '@/mixins/liveSetting';
import { uid } from 'uid';
import { mapState } from 'vuex';
import CommentAction from './_comment-action';
import CommentItem from './_comment-item';
import { formatUsername, getColor, sortListByTime } from './helper';
BScroll.use(MouseWheel);
import { livePhraseList, getCommentList, unAllowComment, deleteComment, queryUserTag } from '@/api/live'
import EventBus from '@/utils/eventBus'
export default {
  name: 'comment',
  components: {
    CommentItem,
    CommentAction,
  },
  mixins: [liveInfo, liveSetting,],
  data() {
    return {
      currentCommentIndex: -1,
      currentComment: null,
      show: false,
      page: 1, // 评论列表分页
      pageSize: 10, // 评论列表分页尺寸
      list: [], // 评论列表
      moreList: [], // 更多信息列表
      loaded: false, // 是否加载完毕
      totalCount: 0, // 商品总数
      placeholderControl: false,
      timer: null,
      count: 0,
      commonLanguageList: [],
      actionlist: [
        {
          name: '禁言',
          id: 1,
          disabled: true

        },
        {
          name: '回复',
          id: 2

        },
        {
          name: '删除',
          id: 3
        },
      ],
    };
  },
  computed: {
    ...mapState({
      user(state) {
        return state.user;
      },
    }),
  },

  watch: {
    mix_liveId: {
      async handler(v) {
        if (!v) return;
        this.subscribeReward(v); // 订阅打赏
        this.fetchCommentList(); // 获取评论列表

        this.subscribeIM(v); // IM
      },
      immediate: true, // 进入页面也立即执行
    },
  },
  mounted() {
    this.initScroll();
    this.getPhraseList()
  },
  methods: {
    handleSelect(item, index) {
      if (this.getCommentActionActive()) return
      this.currentComment = item;
      this.currentCommentIndex = index;
      this.actionlist[0].disabled = this.isAdmin(item.source);
      this.show = true

    },
    async deleteComment() {
      await deleteComment({ liveId: this.mix_liveId, msgSeq: this.currentComment.msgSeq });
      uni.showToast({
        title: '删除成功',
        icon: 'none',
      })
    },
    isAdmin(source) {
      return source === SourceEnum.B || source === SourceEnum.Android || source === SourceEnum.Ios;
    },
    async selectClick(item) {
      switch (item.id) {
        case 1:
          await unAllowComment({ liveId: this.mix_liveId, userId: this.currentComment.userId });
          uni.showToast({
            title: '禁言成功',
            icon: 'none',
          })
          break;
        case 2:
          EventBus.$emit('reply', this.currentComment)
          break;
        case 3:
          this.deleteComment()
          break;

        default:
          break;
      }
    },
    reload() {
      window.location.reload();
    },
    async getPhraseList() {
      const res = await livePhraseList({
        liveId: this.mix_liveId,
        phraseType: 1
      });
      this.commonLanguageList = res.list
    },

    subscribeIM(liveId) {
      console.log(SystemNoticeEnum)
      this.$tim.onGroup(liveId, SystemNoticeEnum.commentAdd, this.handleMessageReceivedCallBack);

      this.$tim.onGroup(liveId, SystemNoticeEnum.commentDel, res => {
        this.total -= 1;
        this.list.splice(
          this.list.findIndex(comment => {
            return comment.msgSeq === res.msgSeq;
          }),
          1,
        );
        this.moreList.splice(
          this.moreList.findIndex(comment => {
            return comment.msgSeq === res.msgSeq;
          }),
          1,
        );
      });
      setTimeout(() => {
        this.$tim.getGroupOnlineMemberCount(liveId).then(res => {
          // todo
        });
      }, 5000);
    },
    // im推送消息
    async handleMessageReceivedCallBack(data) {
      console.log(data)
      if (data.type === 1) {
        if (this.count === 2) return
        this.count += 1
      }

      const res = await queryUserTag({ userId: data.userId });
      console.log(res)
      data.tagNames = res.tagList || [];

      // 不是管理员且隐私设置开启需要脱敏
      if (this.mix_audiencePrivacyProtection) {
        if (data.source !== SourceEnum.B && data.source !== SourceEnum.Android && data.source !== SourceEnum.Ios) {
          data.avatar =
            'https://weilebo-img.oss-cn-hangzhou.aliyuncs.com/icon/bNRkecaeTykciCZaasC4SGSwPCCGTrXD.svg';
          data.username = formatUsername(data.username);
        }
        if (data.v) {
          data.avatar =
            'https://weilebo-img.oss-cn-hangzhou.aliyuncs.com/icon/bNRkecaeTykciCZaasC4SGSwPCCGTrXD.svg';
          data.username = formatUsername(data.username);
        }
        if (data.replyUsername) {
          data.content = data.content.replace(`@${data.replyUsername}`, '');
          data.replyUsername = formatUsername(data.replyUsername);
        }
      }
      // type:1 普通评论  type 2：红包评论 type:3 红包领取记录
      if (data.type !== 2) {
        if (this.list.find(item => item.msgSeq === data.msgSeq)) {
          return;
        }
        data.color = getColor();
        if (this.isBottom()) {
          this.list.push(data);
          this.scrollToBottom(500);
        } else {
          // 竖屏直播中更多消息不展示红包领取记录
          if (data.type !== 3) {
            this.moreList.push(data);
          }
        }
      }
    },
    //  订阅评论MQTT信息 删除评论 callback
    subscribeCommentDelCallback(commentId) {
      const index = this.list.findIndex(item => item.commentId === commentId);
      this.list.splice(index, 1);
    },
    //  打赏mqtt 订阅
    subscribeReward(liveId) {
      this.$tim.onGroup(liveId, 'reward', this.subscribeRewardCallback);
    },
    //  打赏mqtt callback
    subscribeRewardCallback(data) {
      // 不是管理员且隐私设置开启需要脱敏
      const commentData = {
        commentId: uid(),
        ...data,
        isReward: true,
        color: getColor(),
      };
      if (this.isBottom()) {
        this.list.push(commentData);
        this.scrollToBottom();
      } else {
        this.moreList.push(commentData);
      }
    },
    // 获取评论列表
    async fetchCommentList() {
      let list = await getCommentList({
        page: this.page,
        pageSize: this.pageSize,
        liveId: this.mix_liveId,
      });
      list = list || [];
      if (list.length < this.pageSize) {
        this.loaded = true;
      }
      // 对返回的数据根据时间从小到达排序
      const newList = sortListByTime(list).map(item => {
        let content = item.content;
        item.replyUsername = item.replyUserName;
        if (item.replyUsername) {
          content = item.content.replace(`@${item.replyUsername}`, '');
        }
        return {
          ...item,
          content,
        };
      });
      this.list = [...newList, ...this.list];
      if (this.mix_prompt) {
        if (this.list.length == 0) {
          this.list.push({ tips: '友情提示：平台倡导绿色健康直播，严禁在直播间出现违法违规、低俗血暴、吸烟酗酒、诈骗赌博等不良内容。若有违反，平台有权对您采取包括暂停支付收益、冻结或封禁账号等措施。' })
        } else if (!this.hasKey(this.list, 'tips')) {
          this.list.push({ tips: '友情提示：平台倡导绿色健康直播，严禁在直播间出现违法违规、低俗血暴、吸烟酗酒、诈骗赌博等不良内容。若有违反，平台有权对您采取包括暂停支付收益、冻结或封禁账号等措施。' })
        }
      }
      this.fetchCommentListUntilFillContainer();
      this.page = this.page + 1;
      this.scrollToBottom();
    },
    hasKey(array, key) {
      return array.some(obj => key in obj);
    },
    // 持续获取列表直到数据占满评论容器为止
    async fetchCommentListUntilFillContainer() {
      await this.$nextTick();
      if (!this.$refs.commentListRef) {
        return;
      }
      const { scrollHeight } = this.$refs.commentListRef;
      if (scrollHeight <= this.$refs.commentRef.scrollHeight && !this.loaded) {
        this.fetchCommentList();
      }
    },
    // 评论列表滚动效果实例化
    async initScroll() {
      await this.$nextTick();
      this.scroll = new BScroll(this.$refs.commentListWrapRef, {
        mouseWheel: {
          speed: 20,
          invert: false,
          easeTime: 300,
        },
        scrollY: true,
        bounce: false,
        click: true,
      });
      this.scroll.on('scrollEnd', this.scrollEnd);
      this.scroll.on('touchEnd', this.touchEnd);
    },
    // 下拉加载数据: 1. 获取评论列表数据 2. 找到未获取数据之前评论列表的第一个元素, 并让滚动定位至该元素
    async scrollEnd({ y }) {
      if (y !== 0 || this.loaded) {
        return;
      }

      const el = [...this.$refs.commentListRef.children].find(ele => {
        return ele.style.display !== 'none';
      });
      console.log(el);
      await this.fetchCommentList();
      await this.$nextTick();
      await this.scroll.refresh();
      if (el) {
        this.scroll.scrollToElement(el, 0, 0, -20);
      }
    },
    touchEnd() {
      if (this.isBottom()) {
        // 滚动的时候, 当触达底部的时候, 和点击更多消息处理一致
        this.more();
      }
    },
    updatePlaceholderControl() {
      this.placeholderControl = true;
    },
    // 发送评论
    async commentActionSend(data) {
      const msg = notRepeat([data], [...this.list, ...this.moreList])[0];
      if (!msg) {
        return;
      }

      this.list.push(...this.moreList, {
        ...data,
        color: getColor(),
      });
      this.moreList = [];
      this.scrollToBottom(500);
    },
    // 滚动至底部
    async scrollToBottom(time = 0) {
      await this.$nextTick();
      const commentItemRef = this.$refs.commentItemRef;
      if (!commentItemRef) {
        return;
      }
      await this.scroll.refresh();
      // const lastCommentItem = commentItemRef[commentItemRef.length - 1]

      const el = [...this.$refs.commentListRef.children].reverse().find(ele => {
        return ele.style.display !== 'none';
      });
      if (el) {
        this.scroll.scrollToElement(el, time);
      }
    },
    // xx 条新消息点击处理
    more() {
      this.list = [...this.list, ...this.moreList];
      this.moreList = [];
      this.clearComments();
      this.scrollToBottom(500);
    },
    // 节点过多的时候，清除节点, 防止页面卡顿
    clearComments() {
      if (this.list.length >= 50) {
        // 只保留最后第一个分页的数据
        this.list = [...this.list].slice(-this.pageSize);
        this.page = 2;
        this.loaded = false;
      }
    },
    // 评论列表是否到达底部
    isBottom() {
      const { commentListWrapRef, commentListRef } = this.$refs;
      if (!commentListWrapRef || !commentListRef) {
        return false;
      }
      const listWrapBottom = commentListWrapRef.getBoundingClientRect().bottom;
      const listBottom = commentListRef.getBoundingClientRect().bottom;
      return listBottom - listWrapBottom < 10;
    },
    // 获取 CommentActionRef 的 active
    getCommentActionActive() {
      if (!this.$refs.commentActionRef) {
        return false;
      }
      return this.$refs.commentActionRef.active;
    },
    // 发送评论
    async send(item) {
      this.$tim.updateUserInfo({ avatar: this.user.avatarIM, username: this.user.nicknameIM });
      const res = await this.$tim
        .sendMessage(this.mix_liveId, {
          content: `${item}`,
          v: this.user.nickname !== this.user.nicknameIM ? 1 : 0,
        })
        .catch(err => {
          this.$toast(err.message);
        });
      if (!res) {
        return;
      }
      this['live/liveInfoUpdate']({
        ...this.mix_liveInfo,
        hotValue: this.mix_liveInfo.hotValue + 1
      });
      // 隐私设置开启
      if (this.mix_audiencePrivacyProtection) {
        res.avatar =
          'https://weilebo-img.oss-cn-hangzhou.aliyuncs.com/icon/bNRkecaeTykciCZaasC4SGSwPCCGTrXD.svg';
        res.username = formatUsername(res.username);
      }
      this.commentActionSend(res);
      // this.active = false;
      // this.content = '';
    },
  },
  beforeDestroy() {
    this.timer && clearInterval(this.timer);
  }
};
</script>

<style lang="scss" scoped>
.up-comment {
  position: absolute;
  bottom: 0 !important;
  bottom: constant(safe-area-inset-bottom);
  bottom: env(safe-area-inset-bottom);
  z-index: 110;
  width: 100%;
  color: #fff;
}

.up-comment--active {
  bottom: 0;
}

.up-comment--placeholder-control {
  bottom: 0;
  bottom: calc(0 + constant(safe-area-inset-bottom));
  bottom: calc(0 + env(safe-area-inset-bottom));
}

.up-comment--placeholder-control.up-comment--active {
  bottom: 0;
  z-index: 20;
}

.up-comment__list-wrap {
  position: relative;
  width: 262px;
  height: 170px;
  margin-left: 10px;
  margin-bottom: 10px;
  overflow: hidden;

  .ui-icon-loading {
    display: block;
    transform: scale(0.8);
  }
}

.up-comment--placeholder-control.up-comment--active .up-comment__list-wrap {
  margin-bottom: 34px;
}

.up-comment__list-inner {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 100%;

  ul {
    overflow: hidden;
  }
}

.up-comment__more {
  position: absolute;
  bottom: 70px;
  left: 10px;
  padding: 0 8px;
  font-size: 12px;
  line-height: 24px;
  color: rgb(0, 136, 255);
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 3px 10px 0 rgba(0, 0, 0, 0.2);
}

.up-comment__praise {
  right: 0;
}

.task-center {
  position: absolute;
  top: 16px;
  right: 16px;
  z-index: 2;
  width: 50px;

  .after-show--engine {
    position: relative;
    font-style: unset;

    &::before {
      position: absolute;
      bottom: 0;
      left: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 15px;
      font-size: 10px;
      color: #fff;
      text-align: center;
      content: attr(data-before);
      background: #295EFF;
      border-radius: 9px;
    }
  }
}

.up-comment-layout {
  position: absolute;
  top: 88px;
  right: 16px;
  z-index: 2;
  min-height: 200px;
}

@media screen and (min-width: 768px) {
  .up-comment__lottery {
    text-align: right;
  }

  .up-comment {
    z-index: 2;
  }
}

.sideCommon {
  padding: 0 10px;
}

.commonLanguage {
  display: flex;
  overflow-x: scroll;
  white-space: nowrap;

  div {
    padding: 3px 6px;
    margin-right: 8px;
    font-size: 12px;
    color: #FFF;
    cursor: pointer;
    background: rgba(0, 0, 0, 0.3);
    border-radius: 12px;
  }
}
</style>
